package zpe.controledeacesso.service;


import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import zpe.controledeacesso.model.bean.GrupoDeUsuario;
import zpe.controledeacesso.model.bean.Modulo;
import zpe.controledeacesso.model.bean.NivelAcesso;
import zpe.controledeacesso.model.bean.Usuario;
import zpe.controledeacesso.util.UsuarioUtil;
import zpe.genericcrud.service.GenericService;

@Service
public class ModuloService extends GenericService<Modulo> {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Autowired private GrupoDeUsuariosService serviceGrupoDeUsuarios;
	
	@Autowired private UsuarioService serviceUsuario;
	
	public UsuarioService getServiceUsuario() {
		return serviceUsuario;
	}

	public void setServiceUsuario(UsuarioService serviceUsuario) {
		this.serviceUsuario = serviceUsuario;
	}

	public GrupoDeUsuariosService getServiceGrupoDeUsuarios() {
		return serviceGrupoDeUsuarios;
	}

	public void setServiceGrupoDeUsuarios(
			GrupoDeUsuariosService serviceGrupoDeUsuarios) {
		this.serviceGrupoDeUsuarios = serviceGrupoDeUsuarios;
	}
	
	@Transactional(propagation=Propagation.REQUIRED, rollbackFor = {RuntimeException.class})
	public void save(Modulo modulo) {
		
		insert(modulo);
		
		GrupoDeUsuario grupoDeUsuario = new GrupoDeUsuario();
		grupoDeUsuario.setModulo(modulo);
		grupoDeUsuario.setDescricao("MASTER");
		grupoDeUsuario.setNivelDeAcesso( NivelAcesso.MASTER );
		grupoDeUsuario.setDataCadastro(new Date());
		serviceGrupoDeUsuarios.insert(grupoDeUsuario);
		
		Usuario usuario = UsuarioUtil.getUsuarioLogado();
		usuario.getGrupos().add(grupoDeUsuario);
		
		serviceUsuario.update(usuario);
		
	}
	
	@Override
	@Transactional(propagation=Propagation.REQUIRED, rollbackFor = {RuntimeException.class})
	public void removeAll(Collection<Modulo> collection) {
		List<Modulo> exclusao = new ArrayList<Modulo>();
		for( Modulo m : collection ){
			List<GrupoDeUsuario> grupos = getServiceGrupoDeUsuarios().findByModulo( m );
			if( !grupos.isEmpty() ){//Alternativa para evitar a excessão de objetos diferentes com o mesmo idenrificador da classe Modulo
				exclusao.add( grupos.get(0).getModulo() );
			}
			getDao().getEntityManager().deleteAll( grupos );
		}
		if( !exclusao.isEmpty() ){
			super.removeAll( exclusao );
		}else{	
			super.removeAll(collection);
		}
	}

	public boolean findModuloExistente(String descricao) {
		DetachedCriteria dc = DetachedCriteria.forClass(Modulo.class);
		dc.add(Restrictions.eq("descricao", descricao));
		
		return !getDao().getEntityManager().findByCriteria(dc).isEmpty();
	}

	public boolean findModuloExistente(Modulo entity) {
		DetachedCriteria dc = DetachedCriteria.forClass(Modulo.class);
		dc.add(Restrictions.eq("descricao", entity.getDescricao()));
		dc.add(Restrictions.not(Restrictions.eq("id", entity.getId())));
		
		return !getDao().getEntityManager().findByCriteria(dc).isEmpty();
	}	
}